#include <linux/module.h>

#include "../include/testing_commands.h"
#include "print_test.h"

struct tester_data TESTER;


char glob;

asm("hmm:\n\t"
    "int $5\n\t"
);




inline int f(int x) {
  return x+100;
}


void set_comm(void) {
  u64 hmm_addr;
  asm volatile("movq $hmm, %0" : "=r" (hmm_addr));
  
  //PML4E -> PDPTE
  map   (0, 1, 1);
  flags (0, 1, PF_PRESENT);
  
  //PDPTE -> PDE
  map   (1, 1, 2);
  flags (1, 1, PF_PRESENT);
  
  //PDE -> PTE
  map   (2, 1, 3);
  flags (2, 1, PF_PRESENT);
  
  //PTE -> 4kb page
  map   (3, 1, 4);
  flags (3, 1, PF_PRESENT);
  
  comm  ("read 1.1.1.1", CMD_READ, vaddr64_5(1,1,1,1,17), -1);
  /*comm  ("write 1.1.1.1", CMD_WRITE, vaddr64_5(1,1,1,1,17), 4);
  comm  ("run 1.1.1.1", CMD_RUN, vaddr64_5(1,1,1,1,17), 4);
  
  uflags (3, 1, PF_PRESENT);
  noop ("@set P flag to 0");
  
  comm  ("read 1.1.1.1", CMD_READ, vaddr64_5(1,1,1,1,17), 4);
  comm  ("write 1.1.1.1", CMD_WRITE, vaddr64_5(1,1,1,1,17), 4);
  comm  ("run 1.1.1.1", CMD_RUN, vaddr64_5(1,1,1,1,17), 4);
  
  comm  ("@invlpg", CMD_INV, vaddr64_5(1,1,1,1,17), 4);
  
  comm  ("read 1.1.1.1", CMD_READ, vaddr64_5(1,1,1,1,17), 4);
  comm  ("write 1.1.1.1", CMD_WRITE, vaddr64_5(1,1,1,1,17), 4);
  comm  ("run 1.1.1.1", CMD_RUN, vaddr64_5(1,1,1,1,17), 4);*/
   
  comm  ("flush", CMD_FLUSH, 0, 0);
  comm  ("end", CMD_END, 0, 0);
}



static int my_init(void)
{
  info("\n=======begin=======\n");
  init_tester();
  set_comm();
  
  info("contexts initialized\n");
  
  
  print_test();
  run_test();
  
  
  
  free_memory();
  
  info("\nglob: %d\n", (int)glob);
  info("debug: %llu\n", debug);
  
  
  info("\nfinish\n");
  
  return 0;
}

static void my_exit(void) {
  info("exit\n");
}

module_init(my_init);
module_exit(my_exit);
